package com.heima.article.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.heima.article.entity.ApArticle;
import com.heima.article.entity.ApArticleContent;
import com.heima.article.entity.ApAuthor;
import com.heima.article.mapper.ApArticleMapper;
import com.heima.article.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heima.common.enums.AppHttpCodeEnum;
import com.heima.common.exception.LeadException;
import com.heima.common.util.BeanHelper;
import com.heima.model.article.dtos.ArticleDto;
import com.heima.model.article.dtos.ArticleHomeDto;
import com.heima.model.media.dtos.WmNewsResultDTO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.lang.invoke.LambdaConversionException;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * <p>
 * 文章信息表，存储已发布的文章 服务实现类
 * </p>
 *
 * @author HM
 * @since 2023-02-15
 */
@Slf4j
@Service
public class ApArticleServiceImpl extends ServiceImpl<ApArticleMapper, ApArticle> implements ApArticleService {

    @Autowired
    private ApArticleContentService contentService;
    @Autowired
    private ApAuthorService apAuthorService;
    @Autowired
    private FreeMarkService freeMarkService;
    /**
     * 保存文章
     * @param dto
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long saveArticle(WmNewsResultDTO dto) {
//        根据自媒体文章id先查询文章数据
        LambdaQueryWrapper<ApArticle> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ApArticle::getWmNewsId,dto.getId());
        ApArticle apArticle = getOne(queryWrapper);
        if(apArticle==null){
//            新增数据
            apArticle = new ApArticle();
//            根据自媒体用户id查询文章作者
            ApAuthor apAuthor = apAuthorService.findByWmUserId(dto.getWmUserId());
            if(apAuthor != null) {
                apArticle.setAuthorId(apAuthor.getId());
                apArticle.setAuthorName(apAuthor.getName());
            }
            apArticle.setFlag(0);
            apArticle.setLikes(0L);
            apArticle.setViews(0L);
            apArticle.setComments(0L);
            apArticle.setCollection(0L);
            apArticle.setCreatedTime(new Date());
            apArticle.setIsComment(true);
            apArticle.setIsForward(true);
            apArticle.setIsDown(false);
            apArticle.setIsDelete(false);
            apArticle.setWmNewsId(dto.getId());
        }
        apArticle.setTitle(dto.getTitle());
        apArticle.setChannelId(dto.getChannelId());
        apArticle.setLayout(dto.getType());
        apArticle.setImages(dto.getImages());
        apArticle.setLabels(dto.getLabels());
        apArticle.setPublishTime(dto.getPublishTime()==null?new Date():dto.getPublishTime());
//        保存文章表
        boolean b = saveOrUpdate(apArticle);
        if(!b){
            log.error("保存文章失败");
            throw new LeadException(AppHttpCodeEnum.SERVER_ERROR);
        }
//        获取文章id
        Long articleId = apArticle.getId();
//        保存文章内容表
        ApArticleContent apArticleContent = new ApArticleContent();
        apArticleContent.setArticleId(articleId);
        apArticleContent.setContent(dto.getContent());
        boolean b1 = contentService.saveOrUpdate(apArticleContent);
        if(!b1){
            log.error("保存文章内容失败");
            throw new LeadException(AppHttpCodeEnum.SERVER_ERROR);
        }

        log.info("====准备创建静态页面");
//        业务解耦 ，文章详情页面的生成，可以用定时任务做页面的检查，如没有生成就补偿
        freeMarkService.createHtml(apArticle,dto.getContent());
        return articleId;
    }

    @Autowired
    private ApHotArticlesService apHotArticlesService;
    /**
     * app查询首页
     * @param dto
     * @return
     */
    @Override
    public List<ArticleDto> loadArticle(ArticleHomeDto dto,int type) {
        if(dto.getChannelId() != null &&dto.getChannelId()==0){
//            推荐频道，从Redis查询
            return apHotArticlesService.getHotArticle();
        }
//        设置分页条件
        IPage<ApArticle> iPage = new Page<>(1,dto.getSize());
//        设置查询条件
        LambdaQueryWrapper<ApArticle> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.
                eq(ApArticle::getIsDown,false).
                eq(ApArticle::getIsDelete,false);
        if(dto.getChannelId() != null && dto.getChannelId()!=0){
//            添加频道条件
            queryWrapper.eq(ApArticle::getChannelId,dto.getChannelId());
        }
        if(dto.getMaxTime() != null && type==1){
            queryWrapper.gt(ApArticle::getPublishTime,dto.getMaxTime());
            queryWrapper.orderByAsc(ApArticle::getPublishTime);
        }
        if(dto.getMinTime() != null && type ==2){
            queryWrapper.lt(ApArticle::getPublishTime,dto.getMinTime());
            queryWrapper.orderByDesc(ApArticle::getPublishTime);
        }
//        分页查询文章数据
        IPage<ApArticle> apArticleIPage = page(iPage, queryWrapper);
        if(CollectionUtils.isEmpty(apArticleIPage.getRecords())){
            log.info("没有查询到文章");
            throw new LeadException(AppHttpCodeEnum.DATA_NOT_EXIST);
        }
//        构造返回结果
        return BeanHelper.copyWithCollection(apArticleIPage.getRecords(),ArticleDto.class);
    }

    /**
     * 修改article的上下架
     * @param map
     */
    @Override
    public void upOrDown(Map<String, Long> map) {

        Long articleId = map.get("articleId");
        Long enable = map.get("enable");

        ApArticle apArticle = new ApArticle();
        apArticle.setId(articleId);
        apArticle.setIsDown(enable==1?false:true);
        updateById(apArticle);
    }

    /**
     * 分页查询
     * @param page
     * @param size
     * @return
     */
    @Override
    public List<ArticleDto> findByPage(Integer page, Integer size) {

//        设置分页条件
        IPage<ArticleDto> iPage = new Page<>(page,size);
//        多表查询
        List<ArticleDto> list = getBaseMapper().selectArticleAndContent(iPage);

        return list;
    }

    /**
     * 根据文章id 查询文章对象
     * @param articleId
     * @return
     */
    @Override
    public ArticleDto getByArticleId(Long articleId) {
        ArticleDto articleDto = getBaseMapper().selectArticleAndContentById(articleId);
        return articleDto;
    }
}
